from sqlalchemy.orm import Session

from server.app.cloud_ide.model import Ide, IdeEnvironment, IdeImage, IdeRegistry
from server.app.cloud_ide.schema.ide.request.ide_create_request import IdeCreateRequest
from server.app.cloud_ide.schema.ide.request.ide_update_request import IdeUpdateRequest
from server.framework.core.logger import logger
from server.framework.utils.kubernetes.kubernetes_client import KubernetesClient


class IdeService:
    def find_ide_by_name(self, db: Session, name: str) -> Ide:
        entity = db.query(Ide).filter(Ide.name == name).first()
        return entity

    def get_ide_by_id(self, db: Session, id: str):
        entity = db.query(Ide.id, Ide.name, Ide.create_user_name,
                          Ide.ide_environment_id, Ide.status, Ide.created,
                          IdeEnvironment.name.label('ide_environment'),
                          IdeEnvironment.id.label('ide_environment_id'),
                          IdeImage.name.label('ide_image'),
                          IdeImage.id.label('ide_image_id'),
                          IdeRegistry.name.label('ide_registry'),
                          IdeRegistry.id.label('ide_registry_id')) \
            .join(IdeEnvironment, Ide.ide_environment_id == IdeEnvironment.id) \
            .join(IdeImage, Ide.ide_image_id == IdeImage.id) \
            .join(IdeRegistry, IdeImage.ide_registry_id == IdeRegistry.id) \
            .filter(id == Ide.id).one()
        return entity

    def get_ide_list(self, db: Session, user_id: str, name: str, page_size: int, current_page: int):
        query = db.query(Ide.id, Ide.name, Ide.create_user_name,
                         Ide.ide_environment_id, Ide.status, Ide.created,
                         IdeEnvironment.name.label('ide_environment'),
                         IdeEnvironment.id.label('ide_environment_id'),
                         IdeImage.name.label('ide_image'),
                         IdeImage.id.label('ide_image_id'),
                         IdeRegistry.name.label('ide_registry'),
                         IdeRegistry.id.label('ide_registry_id')) \
            .join(IdeEnvironment, Ide.ide_environment_id == IdeEnvironment.id) \
            .join(IdeImage, Ide.ide_image_id == IdeImage.id) \
            .join(IdeRegistry, IdeImage.ide_registry_id == IdeRegistry.id)
        if name is not None:
            query = query.filter(Ide.name.like("%" + name + "%"))
        query = query.filter(Ide.create_user_id == user_id)
        total = query.count()
        items = query.limit(page_size).offset((current_page - 1) * page_size).all()
        return items, total

    def stop_ide(self, db: Session, id: str) -> bool:
        try:
            kubernetes_manager = KubernetesClient()
            kubernetes_manager.delete_ide(id, False)

            ide = db.query(Ide).filter(Ide.id == id).one()
            ide.status = 3
            db.commit()
            return True
        except Exception as e:
            logger.error(e)
            return False

    def start_ide(self, db: Session, id: str) -> bool:
        try:
            ide = db.query(Ide).filter(Ide.id == id).one()
            ide_environment: IdeEnvironment = db.query(IdeEnvironment).filter(
                IdeEnvironment.id == ide.ide_environment_id).one()
            ide_image: IdeImage = db.query(IdeImage).filter(IdeImage.id == ide.ide_image_id).one()
            ide_registry: IdeRegistry = db.query(IdeRegistry).filter(IdeRegistry.id == ide_image.ide_registry_id).one()

            ide_type: str = ''
            if ide_image.ide_type == 0:
                ide_type = 'jupyter'
            if ide_image.ide_type == 1:
                ide_type = 'vscode'
            dynamic_dict = {
                'id': ide.id,
                'storage_class': 'local-path',
                'storage_size': str(ide_environment.max_disk),
                'node_ports': '',
                'ide_type': ide_type,
                'volume_config': '',
                'node_name': '',
                'runtime': 'cpu',
                'extra_volume_config': '',
                'memory_limit': str(ide_environment.max_memory),
                'cpu_limit': str(ide_environment.max_cpu * 1000),
                'memory_request': '',
                'cpu_request': '',
                'image_name': ide_registry.registry + '/' + ide_image.name + ':' + ide_image.version
            }
            kubernetes_manager = KubernetesClient()
            kubernetes_manager.start_ide(dynamic_dict)
            ide.status = 1
            db.commit()
            return True
        except Exception as e:
            logger.error(e)
            return False

    def create_ide(self, db: Session, user_name: str, user_id: str, data: IdeCreateRequest) -> bool:
        try:
            entity = Ide(**data.dict())
            entity.create_user_name = user_name
            entity.create_user_id = user_id
            db.add(entity)
            db.commit()
            return True
        except Exception as e:
            logger.error(e)
            return False

    def delete_ide(self, db: Session, ids: list) -> bool:
        try:
            db.query(Ide).filter(Ide.id.in_(ids)).delete(synchronize_session=False)
            db.commit()
            kubernetes_manager = KubernetesClient()
            for id in ids:
                kubernetes_manager.delete_ide(id, True)
            return True
        except Exception as e:
            logger.error(e)
            return False

    def update_ide(self, db: Session, data: IdeUpdateRequest):
        try:
            db.query(Ide).filter(Ide.id == data.id).update(data.dict())
            db.commit()
            return True
        except Exception as e:
            logger.error(e)
            return False
